/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml.XPath;
using System.Xml;
using System.Text.RegularExpressions;
using DaveSexton.Controls;

namespace DaveSexton.DocProject.Sandcastle.TopicManagement
{
	internal sealed partial class TopicManagementDialog : Form
	{
		#region Public Properties
		public int TopicEditorListWidth
		{
			get
			{
				return topicEditor.ListWidth;
			}
			set
			{
				topicEditor.ListWidth = value;
			}
		}

		public int TopicExplorerWidth
		{
			get
			{
				return splitTreeAndOptions.SplitterDistance;
			}
			set
			{
				splitTreeAndOptions.SplitterDistance = value;
			}
		}

		public MessageBoxOptions MessageBoxOptions
		{
			get
			{
				if (RightToLeft == RightToLeft.Yes)
					return MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading;
				else
					return (MessageBoxOptions) 0;
			}
		}
		#endregion

		#region Private / Protected
		private readonly TopicManager manager;
		private readonly TopicManagementDialogSettings dialogSettings;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="TopicManagementDialog" /> class.
		/// </summary>
		public TopicManagementDialog(TopicManager manager)
			: this()
		{
			if (manager == null)
				throw new ArgumentNullException("manager");

			this.manager = manager;
			
			topicFilters.Manager = manager;
			topicFilters.Hierarchy = topicExplorer;

			topicEditor.Manager = manager;
			topicEditor.Hierarchy = topicExplorer;

			topicProperties.Manager = manager;

			dialogSettings = new TopicManagementDialogSettings(this);
			dialogSettings.Load();
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="TopicManagementDialog" /> class for designer support.
		/// </summary>
		private TopicManagementDialog()
		{
			InitializeComponent();

			// When the designer serializes this assignment the form fails to load in design-time and runtime
			// because the width of the control isn't calculated until after it has been added to the form and 
			// the form's width has been set, since the control is docked, but the default control size is smaller 
			// than the assigned value for the minimum size of Panel2.  The designer-serialized call to SuspendLayout
			// isn't preventing this check and the SplitContainer control does not implement ISupportInitialize.
			this.splitTreeAndOptions.Panel2MinSize = 480;
		}
		#endregion

		#region Methods
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (components != null)
					components.Dispose();

				dialogSettings.Dispose();
			}
			base.Dispose(disposing);
		}
		#endregion

		#region Events
		private readonly object TopicExplorerWidthChangedEvent = new object();
		private readonly object TopicEditorListWidthChangedEvent = new object();

		/// <summary>
		/// Event raised when the <see cref="TopicEditorListWidth"/> property value changes.
		/// </summary>
		[Category("Property Changed")]
		[Description("Event raised when the TopicEditorListWidth property value changes.")]
		public event EventHandler TopicEditorListWidthChanged
		{
			add
			{
				lock (TopicEditorListWidthChangedEvent)
				{
					Events.AddHandler(TopicEditorListWidthChangedEvent, value);
				}
			}
			remove
			{
				lock (TopicEditorListWidthChangedEvent)
				{
					Events.RemoveHandler(TopicEditorListWidthChangedEvent, value);
				}
			}
		}

		/// <summary>
		/// Raises the <see cref="TopicEditorListWidthChanged" /> event.
		/// </summary>
		/// <param name="e"><see cref="EventArgs" /> object that provides the arguments for the event.</param>
		private void OnTopicEditorListWidthChanged(EventArgs e)
		{
			EventHandler handler = null;

			lock (TopicEditorListWidthChangedEvent)
			{
				handler = (EventHandler) Events[TopicEditorListWidthChangedEvent];
			}

			if (handler != null)
				handler(this, e);
		}

		/// <summary>
		/// Event raised when the value of the <see cref="TopicExplorerWidth"/> property changes.
		/// </summary>
		[Category("Property Changed")]
		[Description("Event raised when the value of the TopicExplorerWidth property changes.")]
		public event EventHandler TopicExplorerWidthChanged
		{
			add
			{
				lock (TopicExplorerWidthChangedEvent)
				{
					Events.AddHandler(TopicExplorerWidthChangedEvent, value);
				}
			}
			remove
			{
				lock (TopicExplorerWidthChangedEvent)
				{
					Events.RemoveHandler(TopicExplorerWidthChangedEvent, value);
				}
			}
		}

		/// <summary>
		/// Raises the <see cref="TopicExplorerWidthChanged" /> event.
		/// </summary>
		/// <param name="e"><see cref="EventArgs" /> object that provides the arguments for the event.</param>
		private void OnTopicExplorerWidthChanged(EventArgs e)
		{
			EventHandler handler = null;

			lock (TopicExplorerWidthChangedEvent)
			{
				handler = (EventHandler) Events[TopicExplorerWidthChangedEvent];
			}

			if (handler != null)
				handler(this, e);
		}
		#endregion

		#region Event Handlers
		protected override void OnLoad(EventArgs e)
		{
			manager.LoadTopics(false);

			topicExplorer.Manager = manager;

			base.OnLoad(e);
		}

		protected override void OnFormClosing(FormClosingEventArgs e)
		{
			base.OnFormClosing(e);

			if (!e.Cancel)
			{
				manager.CancelReferenceTopicsBuild(false);

				dialogSettings.Save();
			}
		}

		private void splitTreeAndOptions_SplitterMoved(object sender, SplitterEventArgs e)
		{
			OnTopicExplorerWidthChanged(e);
		}

		private void topicEditor_ListWidthChanged(object sender, EventArgs e)
		{
			OnTopicEditorListWidthChanged(e);
		}

		private void topicExplorer_SelectedTopicChanged(object sender, EventArgs e)
		{
			TopicNode topic = (TopicNode) topicExplorer.SelectedNode;

			if (topic == null)
			{
				topicEditor.Topic = null;
				topicProperties.Topic = null;
			}
			else
			{
				Topic current = topic.Topic;

				if (current.IsApiPlaceholder)
				{
					topicEditor.Topic = null;
					topicProperties.Topic = null;
				}
				else
				{
					topicEditor.Topic = current;
					topicProperties.Topic = current;
				}
			}
		}

		private void topicExplorer_TopicDoubleClick(object sender, TopicNodeEventArgs e)
		{
			Topic topic = e.Node.Topic;
			TopicType type = topic.TopicType;

			switch (type)
			{
				case TopicType.Container:
					// do nothing
					break;
				case TopicType.Html:
				case TopicType.Conceptual:
					manager.OpenConceptualTopic(topic);
					break;
				default:
					tabControl.SelectedTab = commentsTabPage;
					break;
			}
		}

		private void topicExplorer_Properties(object sender, TopicNodeEventArgs e)
		{
			tabControl.SelectedTab = propertiesTab;
		}
		#endregion
	}
}